package com.odais.AE_Planner;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;

import org.andengine.engine.Engine;
import org.andengine.engine.camera.Camera;
import org.andengine.engine.camera.ZoomCamera;
import org.andengine.engine.camera.hud.HUD;
import org.andengine.engine.handler.IUpdateHandler;
import org.andengine.engine.options.EngineOptions;
import org.andengine.engine.options.ScreenOrientation;
import org.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.andengine.entity.primitive.Rectangle;
import org.andengine.entity.scene.IOnSceneTouchListener;
import org.andengine.entity.scene.Scene;
import org.andengine.entity.scene.background.Background;
import org.andengine.entity.shape.IShape;
import org.andengine.entity.sprite.Sprite;
import org.andengine.entity.util.FPSLogger;
import org.andengine.input.touch.TouchEvent;
import org.andengine.input.touch.controller.MultiTouch;
import org.andengine.input.touch.detector.PinchZoomDetector;
import org.andengine.input.touch.detector.PinchZoomDetector.IPinchZoomDetectorListener;
import org.andengine.input.touch.detector.ScrollDetector;
import org.andengine.input.touch.detector.ScrollDetector.IScrollDetectorListener;
import org.andengine.input.touch.detector.SurfaceScrollDetector;
import org.andengine.opengl.font.Font;
import org.andengine.ui.activity.SimpleBaseGameActivity;

import android.app.DatePickerDialog;
import android.app.Dialog;
import android.widget.DatePicker;
import android.widget.Toast;

import com.odais.AE_Handler.Action;
import com.odais.AE_Handler.EngineAction;
import com.odais.AE_Handler.EnginePopulation;
import com.odais.AE_Handler.TouchHandler;
import com.odais.DataManagement.DataListener;
import com.odais.DataManagement.DataManager;
import com.odais.Reservation.ReservationBox;
import com.odais.Reservation.ReservationEntity;
import com.odais.Reservation.ReservationEntityListsHandler;
import com.odais.Reservation.ReservationList;
import com.odais.Reservation.ReservationListModifierManager;

/**
 *
 * @author Lionel DECELLE
 * @since 8 juin 2012 - 10:51:12
 *
 */
public class RoomPlanner extends SimpleBaseGameActivity implements IScrollDetectorListener, IOnSceneTouchListener, IPinchZoomDetectorListener {
// ===========================================================
// Constants
// ===========================================================
static final int CAMERA_WIDTH_INFO = 150;
static final int CAMERA_WIDTH_ROOM = 650;
static final int CAMERA_HEIGHT = 380;


// ===========================================================
// Fields
// ===========================================================

private Font mFont;

private DoubleSceneSplitScreenEngineOdais doubleScene;
private Camera fullCamera;
private Camera infoCamera;
private ZoomCamera roomCamera;
private int camWidthTotal;
private int camHeightTotal;
private Scene mScene;
private Scene infoScene;
private SceneContext mSceneContext;
private SceneContext infoSceneContext;
//private ScrollDetector mScrollDetector;
private ArrayList<Table> tableArrayList;
private ArrayList<People> peopleArrayList;
private boolean magneticPullAllowed;

private SurfaceScrollDetector mScrollDetector;
private PinchZoomDetector mPinchZoomDetector;
private float mPinchZoomStartedCameraZoomFactor;

private TouchHandler touchHandler;
static public EnginePopulation enginePopulation;
private EngineAction engineAction;
private Position enginePosition;

private SceneContext touchedSceneContext;

private int selectedPeople = 0;
private boolean selectedPeopleFound = false;
private int selectedReservation = 0;
private boolean selectedReservationFound = false;
private int selectedTable = 0;
private boolean selectedTableFound = false;
private boolean updateCycleAllowed = false;

private boolean scrollRoom;

private float timeElapsed, oldTimeElapsed;

private ArrayList<HashMap<String, ?>> datain = null;
private HashMap<String, ?> datainHash = null;
private ArrayList<ReservationEntity> reservationEntityArrayList;
private ReservationEntityListsHandler reservationEntityListsHandler;
ReservationList reservationArrayList;
ReservationListModifierManager reservationListModifierManager;
Rectangle reservationBox;
private int reservationOffset;

private HUD roomHUD;

private RoomManager roomManager;


// ===========================================================
// Constructors
// ===========================================================

// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================



@Override
public EngineOptions onCreateEngineOptions() {

this.fullCamera = new Camera(0, 0, CAMERA_WIDTH_INFO+CAMERA_WIDTH_ROOM, CAMERA_HEIGHT);
this.infoCamera = new Camera(0, 0, CAMERA_WIDTH_INFO, CAMERA_HEIGHT);
this.roomCamera = new ZoomCamera(0, 0, CAMERA_WIDTH_ROOM, CAMERA_HEIGHT);
//this.roomCamera.setCenter(CAMERA_WIDTH_INFO+CAMERA_WIDTH_ROOM/2, CAMERA_HEIGHT/2);
camWidthTotal = CAMERA_WIDTH_ROOM;
camHeightTotal = CAMERA_HEIGHT;
//this.roomCamera.setBounds(0, camWidthTotal, 0, camHeightTotal);
//this.roomCamera.setBoundsEnabled(true);
//this.roomCamera.setCenter(CAMERA_WIDTH_INFO + CAMERA_WIDTH_ROOM/2, CAMERA_HEIGHT/2);
//this.roomCamera.setCenter(CAMERA_WIDTH_ROOM/2, CAMERA_HEIGHT/2);

//this.mHasWindowFocused = true;

EngineOptions engineOptions = new EngineOptions(false,ScreenOrientation.LANDSCAPE_FIXED, new RatioResolutionPolicy(CAMERA_WIDTH_INFO+CAMERA_WIDTH_ROOM, CAMERA_HEIGHT), this.infoCamera);
engineOptions.getTouchOptions().setNeedsMultiTouch(true);

//doubleScene = new DoubleSceneSplitScreenEngineOdais(engineOptions, this.infoCamera, this.roomCamera);
//

if(MultiTouch.isSupported(this)) {
	if(MultiTouch.isSupportedDistinct(this)) {
		//Toast.makeText(this, "MultiTouch detected --> Both controls will work properly!", Toast.LENGTH_SHORT).show();
	} else {
		Toast.makeText(this, "MultiTouch detected, but your device has problems distinguishing between fingers.\n\nControls are placed at different vertical locations.", Toast.LENGTH_LONG).show();
	}
} else {
	Toast.makeText(this, "Sorry your device does NOT support MultiTouch!\n\n(Falling back to SingleTouch.)\n\nControls are placed at different vertical locations.", Toast.LENGTH_LONG).show();
}


return engineOptions;
//return new Engine(engineOptions);
}

@Override
public Engine onCreateEngine(EngineOptions pEngineOptions) {
	return doubleScene = new DoubleSceneSplitScreenEngineOdais(pEngineOptions, this.roomCamera, CAMERA_WIDTH_INFO);
}

@Override
public void onCreateResources() {
	enginePopulation = new EnginePopulation();
	touchHandler = new TouchHandler();
	touchHandler.setCamera(roomCamera);
	engineAction = new EngineAction();
	enginePosition = new Position(0, 0);
	touchedSceneContext = new SceneContext(this, mEngine, null);
	
	roomHUD = new HUD();
	this.roomCamera.setHUD(roomHUD);
}


@Override
public Scene onCreateScene() {
	this.mEngine.registerUpdateHandler(new FPSLogger());

	this.mScene = new Scene();
	this.mScene.setBackground(new Background(0.15f, 0.15f, 0.15f));
	this.mScene.setUserData("Room");

//	sellerLVModel = new sellerListViewPendingModel();
//	sellerLVControler = new sellerListViewPendingCtl(sellerLVModel);
//	sellerLVView = new sellerListViewPendingView(sellerLVControler);
//
//	sellerLVModel.addObserver(sellerLVView);
//	datain = sellerLVView.data;

	this.infoScene = new Scene();
	this.infoScene.setBackground(new Background(0.15f, 0.15f, 0.15f, 0));
	this.infoScene.setBackgroundEnabled(true);
	this.infoScene.setUserData("Info");

	this.mSceneContext = new SceneContext(this, mEngine, mScene);
	this.infoSceneContext = new SceneContext(this, mEngine, infoScene);

	this.tableArrayList = new ArrayList<Table>();
	this.peopleArrayList = new ArrayList<People>();
	
	this.reservationEntityArrayList = new ArrayList<ReservationEntity>();
	this.reservationEntityListsHandler = new ReservationEntityListsHandler(reservationEntityArrayList);

	enginePopulation.addList(EnginePopulation.ENGINE_POPULATION_TABLE, this.tableArrayList);
	enginePopulation.addList(EnginePopulation.ENGINE_POPULATION_PEOPLE, this.peopleArrayList);
	enginePopulation.addList(EnginePopulation.ENGINE_POPULATION_RESERVATIONENTITY, this.reservationEntityArrayList);
	

	
	
	reservationListModifierManager = new ReservationListModifierManager(reservationArrayList, reservationEntityListsHandler, infoSceneContext, mSceneContext);
	touchHandler.setReservationListModifierManager(reservationListModifierManager);
	touchHandler.setRoomManager(roomManager);
	
    //RoomManager
	roomManager = new RoomManager(this, enginePopulation, infoSceneContext, mSceneContext, roomCamera, roomHUD);
    roomManager.LoadTiledRoom();

    roomManager.RefreshList();
    

	reservationArrayList = new ReservationList();
	
	DataListener dataListener = new DataListener() {
		
		
		
		@Override
		public void onDataUpdate(ReservationList reservationArrayListUpdated) {

			//Always left panel
			if(reservationArrayListUpdated.getListType().equals(DataManager.UPDATE_TYPE_PENDING_LIST))
			{	
				if(reservationArrayListUpdated!=null)
				{
					reservationArrayList = reservationArrayListUpdated;
					reservationListModifierManager.setReservationList(reservationArrayList);
					reservationListModifierManager.setmRefreshAllowed(true);

					reservationListModifierManager.Refresh();
					
				}
			}
		}
	};
	
	DataManager.setOnDataUpdateListener(dataListener);
	
	
	
	IUpdateHandler tableBusy = new IUpdateHandler() {

		@Override
		public void reset() {
			//All tables are empty at reset
			for(int i=0; i<tableArrayList.size(); i++)
			{
				tableArrayList.get(i).getSprite().setColor(0, 1, 0);
			}
		}

		/* (non-Javadoc)
		 * @see org.anddev.andengine.engine.handler.IUpdateHandler#onUpdate(float)
		 */
		@Override
		public void onUpdate(float pSecondsElapsed)  {
			//All tables are empty at reset
			Sprite currentTable;
			if(updateCycleAllowed)
			{
				for(int i=0; i<tableArrayList.size(); i++)
				{
					currentTable = tableArrayList.get(i).getSprite();
					for(int j=0; j<reservationEntityListsHandler.getReservationBoxRightPanelArrayList().size(); j++)
					{
						if(currentTable.collidesWith((IShape) reservationEntityListsHandler.getReservationBoxRightPanelArrayList().get(j).getShape()))
						{
							if(magneticPullAllowed)
							{
								//MagneticPull is not used in a graphical way anymore
								//peopleHashtable.get(Integer.toString(j)).getSprite().setPosition(currentTable.getX(), currentTable.getY());

								//Take the reservation, give it to the table
								//Kill the messenger
								if(tableArrayList.get(i).setReservation(reservationEntityArrayList.get(j)))
								{
									roomManager.setItemNumberForItem(reservationEntityArrayList.get(j).getReservation(), tableArrayList.get(i).getItemNumber());
									reservationEntityArrayList.remove(j);
								}
							}
							//break;
						}
					}
				}
				updateCycleAllowed = false;
			}
		}
	};


	IUpdateHandler reservationListUpdateHandler = new IUpdateHandler() {

		@Override
		public void reset() {
		}

		@Override
		public void onUpdate(float pSecondsElapsed)  {
//	        timeElapsed += pSecondsElapsed;
//	        
//	        if(timeElapsed-oldTimeElapsed>5)
//	        {
//	        	oldTimeElapsed = timeElapsed;
//				roomManager.RefreshList();
//	        }
		}
};

	this.mScene.registerUpdateHandler(tableBusy);
	this.mScene.registerUpdateHandler(reservationListUpdateHandler);

	this.mScrollDetector = new SurfaceScrollDetector(this);
	this.mPinchZoomDetector = new PinchZoomDetector(this);

	this.mScene.setOnSceneTouchListener(this);
	this.mScene.setTouchAreaBindingOnActionDownEnabled(true);
	this.infoScene.setOnSceneTouchListener(this);
	this.infoScene.setTouchAreaBindingOnActionDownEnabled(true);

//doubleScene.setFirstScene(infoScene);
    doubleScene.setSecondScene(mScene);

	return this.infoScene;
}


// ===========================================================
// Methods
// ===========================================================



protected Dialog onCreateDialog(int id) 
{
	 Calendar c = Calendar.getInstance();
	 int cyear = c.get(Calendar.YEAR);
	 int cmonth = c.get(Calendar.MONTH);
	 int cday = c.get(Calendar.DAY_OF_MONTH);
	 switch (id) {
	 case RoomManager.DATE_DIALOG_ID:
		 return new DatePickerDialog(mSceneContext.getContext(),  mDateSetListener,  cyear, cmonth, cday);
	 }
	 return null;
}

private DatePickerDialog.OnDateSetListener mDateSetListener = new DatePickerDialog.OnDateSetListener() 
{
	 // onDateSet method
	 public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
	 String date_selected = String.valueOf(monthOfYear+1)+" /"+String.valueOf(dayOfMonth)+" /"+String.valueOf(year);
	 roomManager.setRoomHUDDate(date_selected);
	 }
};

@Override
public void onScroll(ScrollDetector pScollDetector, int pPointerID,
		float pDistanceX, float pDistanceY){

	enginePosition.setPosX(pDistanceX);
	enginePosition.setPosY(pDistanceY);
	engineAction.setAll(Action.ACTION_SCROLL, touchedSceneContext, enginePosition, 1);
	touchHandler.ProcessAction(engineAction);
}

@Override
public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {

	if(this.mPinchZoomDetector != null) {
		this.mPinchZoomDetector.onTouchEvent(pSceneTouchEvent);

		if(this.mPinchZoomDetector.isZooming()) {
			this.mScrollDetector.setEnabled(false);
		} else {
			if(pSceneTouchEvent.isActionDown()) {
				this.mScrollDetector.setEnabled(true);
			}
			this.mScrollDetector.onTouchEvent(pSceneTouchEvent);
		}
	} else {
		this.mScrollDetector.onTouchEvent(pSceneTouchEvent);
	}
	

	enginePosition.setPosX(pSceneTouchEvent.getX());
	enginePosition.setPosY(pSceneTouchEvent.getY());
	this.touchedSceneContext.setScene(pScene);
	
	if(pSceneTouchEvent.isActionUp())
	{
		engineAction.setAll(Action.ACTION_UP, touchedSceneContext, enginePosition, 1);
		magneticPullAllowed = true;
		updateCycleAllowed = true;
	}
	else if(pSceneTouchEvent.isActionDown())
	{
		engineAction.setAll(Action.ACTION_DOWN, touchedSceneContext, enginePosition, 1);
		magneticPullAllowed = false;
	}
	else if(pSceneTouchEvent.isActionMove())
	{
		engineAction.setAll(Action.ACTION_MOVE, touchedSceneContext, enginePosition, 1);
	}

	touchHandler.ProcessAction(engineAction);
	
	return true;
}


@Override
public void onScrollStarted(ScrollDetector pScollDetector, int pPointerID,
		float pDistanceX, float pDistanceY) {
}

@Override
public void onScrollFinished(ScrollDetector pScollDetector, int pPointerID,
		float pDistanceX, float pDistanceY) {
}


@Override
public void onPinchZoomStarted(PinchZoomDetector pPinchZoomDetector, TouchEvent pSceneTouchEvent) {
		this.mPinchZoomStartedCameraZoomFactor = this.roomCamera.getZoomFactor();
}

@Override
public void onPinchZoom(PinchZoomDetector pPinchZoomDetector, TouchEvent pTouchEvent, float pZoomFactor) {
	enginePosition.setPosX(pTouchEvent.getX());
	enginePosition.setPosY(pTouchEvent.getY());
	this.touchedSceneContext.setScene(mScene);
	engineAction.setAll(Action.ACTION_ZOOM, touchedSceneContext, enginePosition, this.mPinchZoomStartedCameraZoomFactor * pZoomFactor);
	touchHandler.ProcessAction(engineAction);
}

@Override
public void onPinchZoomFinished(PinchZoomDetector pPinchZoomDetector, TouchEvent pTouchEvent, float pZoomFactor) {
	enginePosition.setPosX(pTouchEvent.getX());
	enginePosition.setPosY(pTouchEvent.getY());
	this.touchedSceneContext.setScene(mScene);
	engineAction.setAll(Action.ACTION_ZOOM, touchedSceneContext, enginePosition, this.mPinchZoomStartedCameraZoomFactor * pZoomFactor);
	touchHandler.ProcessAction(engineAction);
}
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================


}